using Firestarter.DB.Schema.Logic;
using Habanero.Testability;
using NUnit.Framework;

namespace Firestarter.DB.Schema.Test.Logic
{
    [TestFixture]
    public class TestCreateTableSqlBuilderSQLServer : TestCreateTableSqlBuilder
    {
        protected override CreateTableSqlBuilder CreateBuilder(string tableName)
        {
            return new CreateTableSqlBuilder_SqlServer(tableName);
        }

        protected override string Enclose(string name)
        {
            return string.Format("[{0}]", name);
        }

        private static string GetRandomString()
        {
            return RandomValueGen.GetRandomString();
        }
        [Test]
        public override void Test_AddColumn_NotNullable_NotAutoIncrement()
        {
            //---------------Set up test pack-------------------
            string tableName = GetRandomString();
            CreateTableSqlBuilder sqlBuilder_SqlBuilderCreateTable = CreateBuilder(tableName);
            const string dataType = "int";
            string columnName = GetRandomString();
            //-------------Assert Preconditions -------------

            //---------------Execute Test ----------------------
            sqlBuilder_SqlBuilderCreateTable.AddColumn(columnName, dataType, null, null, false, false);
            //---------------Test Result -----------------------
            string expectdSql = string.Format("{0} {1} NOT NULL", Enclose(columnName), dataType);
            Assert.AreEqual(expectdSql, sqlBuilder_SqlBuilderCreateTable.Columns[0]);
        }

        [Test]
        public override void Test_AddColumn_NotNullable_AutoIncrement()
        {
            //---------------Set up test pack-------------------
            string tableName = GetRandomString();
            CreateTableSqlBuilder sqlBuilder_SqlBuilderCreateTable = CreateBuilder(tableName);
            const string dataType = "int";
            string columnName = GetRandomString();
            //-------------Assert Preconditions -------------

            //---------------Execute Test ----------------------
            sqlBuilder_SqlBuilderCreateTable.AddColumn(columnName, dataType, null, null, false, true);
            //---------------Test Result -----------------------
            string expectdSql = string.Format("{0} {1} NOT NULL IDENTITY(1,1)", Enclose(columnName), dataType);
            Assert.AreEqual(expectdSql, sqlBuilder_SqlBuilderCreateTable.Columns[0]);
        }

        [Test]
        public override void Test_AddColumn_Nullable_NotAutoIncrement()
        {
            //---------------Set up test pack-------------------
            string tableName = GetRandomString();
            CreateTableSqlBuilder sqlBuilder_SqlBuilderCreateTable = CreateBuilder(tableName);
            const string dataType = "int";
            string columnName = GetRandomString();
            //-------------Assert Preconditions -------------

            //---------------Execute Test ----------------------
            sqlBuilder_SqlBuilderCreateTable.AddColumn(columnName, dataType, null, null, true, false);
            //---------------Test Result -----------------------
            string expectdSql = string.Format("{0} {1} NULL", Enclose(columnName), dataType);
            Assert.AreEqual(expectdSql, sqlBuilder_SqlBuilderCreateTable.Columns[0]);
        }

        [Test]
        public override void Test_AddColumn_Nullable_AutoIncrement()
        {
            //---------------Set up test pack-------------------
            string tableName = GetRandomString();
            CreateTableSqlBuilder sqlBuilder_SqlBuilderCreateTable = CreateBuilder(tableName);
            const string dataType = "int";
            string columnName = GetRandomString();
            //-------------Assert Preconditions -------------

            //---------------Execute Test ----------------------
            sqlBuilder_SqlBuilderCreateTable.AddColumn(columnName, dataType, null, null, true, true);
            //---------------Test Result -----------------------
            string expectdSql = string.Format("{0} {1} NULL IDENTITY(1,1)", Enclose(columnName), dataType);
            Assert.AreEqual(expectdSql, sqlBuilder_SqlBuilderCreateTable.Columns[0]);
        }

        [Test]
        public override void Test_AddForeignKey_ShouldCreateFKConstraint()
        {
            //---------------Set up test pack-------------------
            string tableName = GetRandomString();
            CreateTableSqlBuilder sqlBuilderCreateTable = CreateBuilder(tableName);
            string referencedTableName = GetRandomString();
            string foreignKeyName = GetRandomString();
            const string parentColumnNameList = "field1FK, field2FK";
            string expectedParentColumnNameList = Enclose("field1FK") + ", " + Enclose("field2FK");
            const string referencedColumnNameList = "field1, field2";
            string expectedReferencedColumnNameList = Enclose("field1") + ", " + Enclose("field2");
            //---------------Assert Precondition----------------

            //---------------Execute Test ----------------------
            sqlBuilderCreateTable.AddForeignKey
                (foreignKeyName, parentColumnNameList, referencedTableName, referencedColumnNameList);
            //---------------Test Result -----------------------
            Assert.AreEqual(1, sqlBuilderCreateTable.ForeignKeys.Count);
            string expectdFKString = string.Format
                ("CONSTRAINT {0} FOREIGN KEY ({1}) REFERENCES {2} ({3})", Enclose(foreignKeyName), expectedParentColumnNameList,
                 Enclose(referencedTableName), expectedReferencedColumnNameList);
            Assert.AreEqual(expectdFKString, sqlBuilderCreateTable.ForeignKeys[0]);
        }

        [Test]
        public override void Test_ForeignKeyGetSQL()
        {
            //---------------Set up test pack-------------------
            string tableName = GetRandomString();
            CreateTableSqlBuilder sqlBuilder_SqlBuilderCreateTable = CreateBuilder(tableName);
            string referencedTableName = GetRandomString();
            string foreignKeyName = GetRandomString();
            const string parentColumnNameList = "field1FK, field2FK";
            string expectedParentColumnNameList = Enclose("field1FK") + ", " + Enclose("field2FK");
            const string referencedColumnNameList = "field1, field2";
            string expectedReferencedColumnNameList = Enclose("field1") + ", " + Enclose("field2");
            sqlBuilder_SqlBuilderCreateTable.AddForeignKey
                (foreignKeyName, parentColumnNameList, referencedTableName, referencedColumnNameList);
            //---------------Assert Precondition----------------
            Assert.AreEqual(1, sqlBuilder_SqlBuilderCreateTable.ForeignKeys.Count);
            //---------------Execute Test ----------------------
            string sql = sqlBuilder_SqlBuilderCreateTable.GetSql();
            //---------------Test Result -----------------------
            string expectdFKString = string.Format
                ("CONSTRAINT {0} FOREIGN KEY ({1}) REFERENCES {2} ({3})",
                Enclose(foreignKeyName), expectedParentColumnNameList,
                Enclose(referencedTableName), expectedReferencedColumnNameList);
            StringAssert.Contains(expectdFKString, sql);
        }
    }
}